﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using XcoAppSpaces.Core.Ports;
using NUnit.Framework;
using XcoAppSpaces.Core;

namespace test.XcoAppSpaces.Core.Error_Reproductions
{
	

	[TestFixture]
	public class testPublishWithSubType
	{
		[Test]
		public void PublishSubType()
		{
			using (XcoAppSpace server = new XcoAppSpace("tcp.port=8001"), client = new XcoAppSpace("tcp.port=8002"))
			{
				server.RunWorker<PubSubWorker, PubSubWorkerImpl>("publisher");
				PubSubWorker pub = client.ConnectWorker<PubSubWorker>("localhost:8001/publisher");

				Port<object> subPort = new Port<object>();
				Port<Exception> pex = new Port<Exception>();
				pub.Post(new Subscribe<object>(subPort));
				Thread.Sleep(200);
				pub.P2.Post("test", pex);

				object received = subPort.Receive(1000).Result;
				Exception ex = (pex.ItemCount > 0) ? pex.Receive().Result : null;
				if (ex != null)
					Console.WriteLine("Error: " + ex);

				Assert.IsNotNull(received);
				Assert.AreEqual("test", received.ToString());
			}
		}

		[Test]
		public void PublishInterface()
		{
			using (XcoAppSpace server = new XcoAppSpace("tcp.port=8001"), client = new XcoAppSpace("tcp.port=8002"))
			{
				server.RunWorker<PubSubWorker2, PubSubWorker2Impl>("publisher");
				PubSubWorker2 pub = client.ConnectWorker<PubSubWorker2>("localhost:8001/publisher");

				Port<IComparable> subPort = new Port<IComparable>();
				Port<Exception> pex = new Port<Exception>();
				pub.Post(new Subscribe<IComparable>(subPort));
				Thread.Sleep(200);
				
				pub.P2.Post("test", pex);
				IComparable received = subPort.Receive(1000).Result as IComparable;
				Exception ex = (pex.ItemCount > 0) ? pex.Receive().Result : null;
				if (ex != null)
					Console.WriteLine("Error: " + ex);
				Assert.IsNotNull(received);
				Assert.AreEqual("test", received);

				pub.P2.Post(123, pex);
				received = subPort.Receive(1000).Result as IComparable;
				ex = (pex.ItemCount > 0) ? pex.Receive().Result : null;
				if (ex != null)
					Console.WriteLine("Error: " + ex);
				Assert.IsNotNull(received);
				Assert.AreEqual(123, received);
			}
		}

		internal class PubSubWorker : PortSet<Subscribe<object>, Unsubscribe<object>, string>
		{
		}

		internal class PubSubWorkerImpl : PubSubWorker
		{
			private XcoPublisher<object> publisher = new XcoPublisher<object>();

			[XcoConcurrent]
			void Process(string test)
			{
				publisher.Publish(test);
			}
		}

		internal class PubSubWorker2 : PortSet<Subscribe<IComparable>, Unsubscribe<IComparable>, IComparable>
		{
		}

		internal class PubSubWorker2Impl : PubSubWorker2
		{
			private XcoPublisher<IComparable> publisher = new XcoPublisher<IComparable>();

			[XcoConcurrent]
			void Process(IComparable test)
			{
				publisher.Publish(test);
			}
		}
	}
}
